package cn.com.dbridge.common.websocket.netty.handler;

import cn.com.dbridge.common.websocket.common.NettyCode;
import cn.com.dbridge.common.websocket.domain.DeviceInfo;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.*;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@ChannelHandler.Sharable
public class MessageHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {


    /**
     * <strong>Please keep in mind that this method will be renamed to
     * {@code messageReceived(ChannelHandlerContext, I)} in 5.0.</strong>
     * <p>
     * Is called for each message of type {@link WebSocketFrame}.
     *
     * @param ctx the {@link ChannelHandlerContext} which this {@link SimpleChannelInboundHandler}
     *            belongs to
     * @param msg the message to handle
     * @throws Exception is thrown if an error occurred
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        DeviceInfo deviceInfo = DeviceInfoManager.getDeviceInfo(ctx.channel());
        if (deviceInfo != null && deviceInfo.isAuth()) {
            JSONObject json = JSONObject.parseObject(msg.text());
            DeviceInfoManager.broadcastMessage(deviceInfo.getUserId(), deviceInfo.getNick(), json.getString("mess"));
        }
    }

    /**
     * Calls {@link ChannelHandlerContext#fireChannelUnregistered()} to forward
     * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}.
     */
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        DeviceInfoManager.removeChannel(ctx.channel());
        DeviceInfoManager.broadCastSystemInfo(NettyCode.SYS_USER_COUNT, DeviceInfoManager.getAuthUserCount());
        super.channelUnregistered(ctx);
    }

    /**
     * Calls {@link ChannelHandlerContext#fireExceptionCaught(Throwable)} to forward
     * to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("connection error and close the channel", cause);
        DeviceInfoManager.removeChannel(ctx.channel());
        DeviceInfoManager.broadCastSystemInfo(NettyCode.SYS_USER_COUNT, DeviceInfoManager.getAuthUserCount());
    }

}
